using System;
using System.Collections.Generic;
using UnityEngine;

namespace FormicArch.MVVM.Managers
{
    public class ModelManager : IManager
    {
        private static ModelManager _instance;
        public static ModelManager Instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new ModelManager();
                }
                return _instance;
            }
        }

        private readonly Dictionary<Type, object> _models = new Dictionary<Type, object>();
        private bool _isInitialized;

        private ModelManager() { }

        public void Initialize()
        {
            if (_isInitialized) return;
            _isInitialized = true;
        }

        public void Update()
        {
            // 更新所有 Model
            foreach (var model in _models.Values)
            {
                if (model is IUpdata updatable)
                {
                    updatable.Update();
                }
            }
        }

        public void OnDestroy()
        {
            foreach (var model in _models.Values)
            {
                if (model is IDisposable disposable)
                {
                    disposable.Dispose();
                }
            }
            _models.Clear();
            _isInitialized = false;
        }

        public void Dispose()
        {
            OnDestroy();
        }

        public T GetModel<T>() where T : class, new()
        {
            var type = typeof(T);
            if (!_models.ContainsKey(type))
            {
                _models[type] = new T();
            }
            return _models[type] as T;
        }

        public void RegisterModel<T>(T model) where T : class
        {
            var type = typeof(T);
            if (_models.ContainsKey(type))
            {
                Debug.LogWarning($"Model of type {type.Name} already exists. Overwriting...");
            }
            _models[type] = model;
        }

        public void UnregisterModel<T>() where T : class
        {
            var type = typeof(T);
            if (_models.ContainsKey(type))
            {
                if (_models[type] is IDisposable disposable)
                {
                    disposable.Dispose();
                }
                _models.Remove(type);
            }
        }

        public bool HasModel<T>() where T : class
        {
            return _models.ContainsKey(typeof(T));
        }
    }

    public interface IUpdata
    {
        void Update();
    }
}